﻿namespace DesignModeConsole.创建型.建造者模式;

/// <summary>
/// 资源池配置类
/// </summary>
public class ResourcePoolConfig
{
    public ResourcePoolConfig(string name)
    {
        if (name == null)
            throw new ArgumentNullException(nameof(name));
        Name = name;
    }

    public ResourcePoolConfig(string name, int? maxTotal, int? maxIdle, int? minIdle)
    {
        if (name == null)
            throw new ArgumentNullException(nameof(name));

        Name = name;
        if (maxTotal != null)
        {
            if (maxTotal <= 0)
                throw new ArgumentOutOfRangeException(nameof(maxTotal));

            MaxTotal = maxTotal.Value;
        }
        if (maxIdle != null)
        {
            if (maxIdle <= 0)
                throw new ArgumentOutOfRangeException(nameof(maxIdle));
            MaxIdle = maxIdle.Value;
        }
        if (minIdle != null)
        {
            if (minIdle <= 0)
                throw new ArgumentOutOfRangeException(nameof(minIdle));

            MinIdle = minIdle.Value;
        }
    }

    /// <summary>
    /// 资源名
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 最大总资源数
    /// </summary>
    public int MaxTotal { get; set; } = 8;

    /// <summary>
    /// 最大空闲资源数量
    /// </summary>
    public int MaxIdle { get; set; } = 8;

    /// <summary>
    /// 最小空闲资源数量
    /// </summary>
    public int MinIdle { get; set; } = 0;

    public void SetMaxTotal(int maxTotal)
    {
        MaxTotal = maxTotal;
    }

    public void SetMaxIdle(int maxIdle)
    {
        MaxIdle = maxIdle;
    }
}

public class ResourcePoolConfig2
{
    public ResourcePoolConfig2(ResourcePoolConfigBuilder builder)
    {
        Name = builder.Name;
        MaxTotal = builder.MaxTotal;
        MaxIdle = builder.MaxIdle;
        MinIdle = builder.MinIdle;
    }

    /// <summary>
    /// 资源名
    /// </summary>
    public string Name { get; }

    /// <summary>
    /// 最大总资源数
    /// </summary>
    public int MaxTotal { get; } = 8;

    /// <summary>
    /// 最大空闲资源数量
    /// </summary>
    public int MaxIdle { get; } = 8;

    /// <summary>
    /// 最小空闲资源数量
    /// </summary>
    public int MinIdle { get; }

    public class ResourcePoolConfigBuilder
    {
        public ResourcePoolConfigBuilder(string name)
        {
            if (name is null)
                throw new ArgumentNullException(nameof(Name));

            Name = name;
        }

        /// <summary>
        ///名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 最大总资源数
        /// </summary>
        public int MaxTotal { get; set; } = 8;

        /// <summary>
        /// 最大空闲资源数量
        /// </summary>
        public int MaxIdle { get; set; } = 8;

        /// <summary>
        /// 最小空闲资源数量
        /// </summary>
        public int MinIdle { get; set; } = 0;

        /// <summary>
        /// 参数校验+构建对象
        /// </summary>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public ResourcePoolConfig2 Build()
        {
            if (Name == null)
                throw new ArgumentNullException(nameof(Name));

            if (MaxTotal <= 0)
                throw new ArgumentOutOfRangeException(nameof(MaxTotal));

            if (MaxIdle <= 0)
                throw new ArgumentOutOfRangeException(nameof(MaxIdle));
            if (MinIdle <= 0)
                throw new ArgumentOutOfRangeException(nameof(MinIdle));

            if (MaxIdle > MaxTotal)
                throw new ArgumentOutOfRangeException(nameof(MaxIdle));

            return new ResourcePoolConfig2(this);
        }

        public ResourcePoolConfigBuilder SetMaxTotal(int maxTotal)
        {
            if (maxTotal <= 0)
                throw new ArgumentOutOfRangeException(nameof(maxTotal));
            MaxTotal = maxTotal;
            return this;
        }

        public ResourcePoolConfigBuilder SetMaxIdle(int maxIdle)
        {
            if (maxIdle <= 0)
                throw new ArgumentOutOfRangeException(nameof(maxIdle));
            MaxIdle = maxIdle;

            return this;
        }

        public ResourcePoolConfigBuilder SetMinIdle(int minIdle)
        {
            if (minIdle <= 0)
                throw new ArgumentOutOfRangeException(nameof(minIdle));
            MinIdle = minIdle;
            return this;
        }
    }
}